home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / bbs / fmail120.zip / FMSTRUCT.ZIP / cfgfile.c next >
C/C++ Source or Header  |  1996-08-28  |  11KB  |  316 lines

  1. /*
  2.    CFGFILE.C
  3.  
  4.    Config file interface routines for FMail 1.20
  5.    Copyright (C) 1996 Folkert J. Wijnstra. All rights reserved.
  6.  
  7.    All information in this document is subject to change at any time
  8.    without prior notice!
  9. */
  10.  
  11.  
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <fcntl.h>
  15. #include <sys\stat.h>
  16. #include <io.h>
  17. #include <time.h>
  18.  
  19. #include "fmstruct.h"
  20. #include "cfgfile.h"
  21. #include "internal.h" /* not necessary for 3rd party programs */
  22.  
  23.  
  24. /* set to non-zero value if automatic conversion is desired */
  25. u16  allowConversion = 0;
  26.  
  27.  
  28. typedef struct
  29. {
  30.    const char     *fileName;
  31.    const u16      recordSize;
  32.    fhandle        handle;
  33.    char           *recBuf;
  34.    char           *revString;
  35.    u16            revNumber;
  36.    const u16      dataType;
  37.    const u16      init;
  38.    u16            status;
  39.    headerType     header;
  40. } configFileInfoType;
  41.  
  42.  
  43. static configFileInfoType fileData[MAX_CFG_FILES] =
  44.    {
  45.     /* CFG_GENERAL */
  46.     {       "FMAIL.CFG", sizeof(configType),    -1, NULL,
  47.                 "FMail Configuration File rev. 1.1\x1a",
  48.                  0x0110, DATATYPE_CF, 'CF', 0 },
  49.     /* CFG_NODES */
  50.     {       "FMAIL.NOD", sizeof(nodeInfoType), -1, NULL,
  51.                 "FMail Node File rev. 1.1\x1a",
  52.                  0x0110, DATATYPE_NO, 'NO', 0 },
  53.     /* CFG_ECHOAREAS */
  54.     {       "FMAIL.AR",  sizeof(rawEchoType),  -1, NULL,
  55.                 "FMail Area File rev. 1.1\x1a",
  56.                  0x0110, DATATYPE_AE, 'AE', 0 },
  57.     /* CFG_AREADEF */
  58.     {       "FMAIL.ARD", sizeof(rawEchoType),  -1, NULL,
  59.                 "FMail Area File rev. 1.1\x1a",
  60.                  0x0110, DATATYPE_AD, 'AD', 0 } };
  61.  
  62.  
  63. static configFileInfoType cfiArr[MAX_CFG_FILES];
  64.  
  65. extern char configPath[128]; /* Path to directory with FMail config files */
  66.  
  67.  
  68.  
  69. s16 openConfig(u16 fileType, headerType **header, void **buf)
  70. {
  71.    pathType areaInfoPath, tempPath;
  72.    fhandle  temphandle;
  73.    uchar    *helpPtr;
  74.    u16        count;
  75.    u16      orgRecSize;
  76.    u16      converted = 0;
  77.  
  78.    if (fileType >= MAX_CFG_FILES) return 0;
  79.  
  80. restart:
  81.    strcpy(areaInfoPath, configPath);
  82.    strcat(areaInfoPath, fileData[fileType].fileName);
  83.  
  84.    memset(&cfiArr[fileType].header, 0, sizeof(headerType));
  85.    cfiArr[fileType].status = 0;
  86.  
  87.    if ((cfiArr[fileType].handle = open(areaInfoPath, O_BINARY|O_RDWR|O_CREAT|O_DENYALL, S_IREAD|S_IWRITE)) == -1)
  88.    {  return 0;
  89.    }
  90.    if (filelength(cfiArr[fileType].handle) == 0)
  91.    {
  92.       strcpy(cfiArr[fileType].header.versionString, fileData[fileType].revString);
  93.       cfiArr[fileType].header.revNumber    = fileData[fileType].revNumber;
  94.       cfiArr[fileType].header.headerSize   = sizeof(headerType);
  95.       cfiArr[fileType].header.recordSize   = fileData[fileType].recordSize;
  96.       cfiArr[fileType].header.dataType     = fileData[fileType].dataType;
  97.       cfiArr[fileType].header.totalRecords = 0;
  98.       cfiArr[fileType].header.lastModified = time(&cfiArr[fileType].header.creationDate);
  99.  
  100.       write(cfiArr[fileType].handle, &cfiArr[fileType].header, sizeof(headerType));
  101.    }
  102.    else
  103.    {
  104.       read(cfiArr[fileType].handle, &cfiArr[fileType].header, sizeof(headerType));
  105.  
  106.       if (memcmp(cfiArr[fileType].header.versionString, "FMail", 5) ||
  107.           (cfiArr[fileType].header.headerSize < sizeof(headerType)) ||
  108.           ((!allowConversion || converted) && cfiArr[fileType].header.recordSize < fileData[fileType].recordSize) ||
  109.       (cfiArr[fileType].header.dataType != fileData[fileType].dataType))
  110.       {
  111. error:   close(cfiArr[fileType].handle);
  112.      cfiArr[fileType].handle = -1;
  113.      *header = NULL;
  114.      *buf = NULL;
  115.      return 0;
  116.       }
  117.       if (cfiArr[fileType].header.recordSize < fileData[fileType].recordSize)
  118.       {
  119.          /* convert old record format */
  120.          strcpy(tempPath, areaInfoPath);
  121.          if ( (helpPtr = strrchr(tempPath, '.')) == NULL )
  122.             goto error;
  123.          strcpy(helpPtr+1, "$$$");
  124.          if ((cfiArr[fileType].recBuf = malloc(fileData[fileType].recordSize)) == NULL)
  125.             goto error;
  126.          if ((temphandle = open(tempPath, O_BINARY|O_RDWR|O_CREAT|O_DENYALL, S_IREAD|S_IWRITE)) == -1)
  127.          {  free(cfiArr[fileType].recBuf);
  128.             goto error;
  129.          }
  130.          orgRecSize = cfiArr[fileType].header.recordSize;
  131.          strcpy(cfiArr[fileType].header.versionString, fileData[fileType].revString);
  132.          cfiArr[fileType].header.revNumber    = fileData[fileType].revNumber;
  133.          cfiArr[fileType].header.headerSize   = sizeof(headerType);
  134.          cfiArr[fileType].header.recordSize   = fileData[fileType].recordSize;
  135.          cfiArr[fileType].header.dataType     = fileData[fileType].dataType;
  136.          time(&cfiArr[fileType].header.lastModified);
  137.          write(temphandle, &cfiArr[fileType].header, sizeof(headerType));
  138.          for ( count = 0; count < cfiArr[fileType].header.totalRecords; count++ )
  139.          {  memset(cfiArr[fileType].recBuf, 0, fileData[fileType].recordSize);
  140.             if ( read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, orgRecSize) != orgRecSize )
  141.             {  free(cfiArr[fileType].recBuf);
  142.                close(temphandle);
  143.                unlink(tempPath);
  144.                goto error;
  145.             }
  146.             if (write(temphandle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) !=
  147.                                                            cfiArr[fileType].header.recordSize)
  148.             {  free(cfiArr[fileType].recBuf);
  149.                close(temphandle);
  150.                unlink(tempPath);
  151.                goto error;
  152.             }
  153.          }
  154.          converted = 1;
  155.          free(cfiArr[fileType].recBuf);
  156.          close(temphandle);
  157.          close(cfiArr[fileType].handle);
  158.          unlink(areaInfoPath);
  159.          rename(tempPath, areaInfoPath);
  160.      cfiArr[fileType].handle = -1;
  161.      *header = NULL;
  162.          *buf = NULL;
  163.          goto restart;
  164.       }
  165.    }
  166.    if ((cfiArr[fileType].recBuf = malloc(cfiArr[fileType].header.recordSize)) == NULL)
  167.       goto error;
  168.    *header = &cfiArr[fileType].header;
  169.    *buf    = cfiArr[fileType].recBuf;
  170.    return 1;
  171. }
  172.  
  173.  
  174. s16 getRec(u16 fileType, s16 index)
  175. {
  176.    if (cfiArr[fileType].handle == -1) return 0;
  177.  
  178.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  179.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  180.    {  return 0;
  181.    }
  182.    if (read(cfiArr[fileType].handle, cfiArr[fileType].recBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  183.    {  return 0;
  184.    }
  185.    return 1;
  186. }
  187.  
  188.  
  189. s16 putRec(u16 fileType, s16 index)
  190. {
  191.    if (cfiArr[fileType].handle == -1) return 0;
  192.  
  193.    *(u16*)cfiArr[fileType].recBuf = fileData[fileType].init;
  194.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  195.              cfiArr[fileType].header.recordSize*(s32)index, SEEK_SET) == -1)
  196.    {  return 0;
  197.    }
  198.    if (write (cfiArr[fileType].handle, cfiArr[fileType].recBuf,
  199.           cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  200.    {  return 0;
  201.    }
  202.    cfiArr[fileType].status = 1;
  203.    return 1;
  204. }
  205.  
  206.  
  207. s16 insRec(u16 fileType, s16 index)
  208. {
  209.    s16  count;
  210.    void *tempBuf;
  211.  
  212.    if (cfiArr[fileType].handle == -1) return 0;
  213.  
  214.    *(u16*)cfiArr[fileType].recBuf = fileData[fileType].init;
  215.  
  216.    if ((tempBuf = malloc(cfiArr[fileType].header.recordSize)) == NULL) return 0;
  217.    count = cfiArr[fileType].header.totalRecords;
  218.  
  219.    while (--count >= index)
  220.    {  if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  221.                 cfiArr[fileType].header.recordSize*(s32)count, SEEK_SET) == -1)
  222.       {  free(tempBuf);
  223.      return 0;
  224.       }
  225.       if (read(cfiArr[fileType].handle, tempBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  226.       {  free(tempBuf);
  227.      return 0;
  228.       }
  229.       if (write(cfiArr[fileType].handle, tempBuf, cfiArr[fileType].header.recordSize) != cfiArr[fileType].header.recordSize)
  230.       {  free(tempBuf);
  231.      return 0;
  232.       }
  233.    }
  234.    free(tempBuf);
  235.    if (lseek(cfiArr[fileType].handle, cfiArr[fileType].header.headerSize+
  236.              cfiArr[fil